//=============================================================================
/**
 *
 *	@file		museum_obj.c
 *	@brief		ポケスロンミュージアム OBJ管理モジュール
 *	@author		hosaka genya
 *	@data		2008.08.06
 *
 */
//=============================================================================
#include "common.h"
#include "gflib/touchpanel.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/brightness.h"
#include "system/pm_str.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/gra_tool.h"
#include "poketool/poke_tool.h"
#include "poketool/pokeicon.h"

#include "museum_util.h"
#include "museum_obj.h"

#include "pkth_museum.naix"
#include "obj_trophy_NANR_LBLDEFS.h"

//=============================================================================
/**
 *								定数定義
 */
//=============================================================================
enum
{
	eID_OAM_POKE_ICON	= 100000,
	eOAM_PAL_POKE_ICON		= 4,			///<
};

//=============================================================================
/**
 *								構造体定義
 */
//=============================================================================
//--------------------------------------------------------------
///	メインワーク
//==============================================================
struct _MUSEUM_OBJ_WORK {
	HEAPID			heapID;

	CATS_SYS_PTR	csp;
	CATS_RES_PTR	crp;
	PALETTE_FADE_PTR pfd;

	ARCHANDLE*		p_arc_pokeicon;
	s8				paloff_pokemonicon;
};



//=============================================================================
/**
 *							プロトタイプ宣言
 */
//=============================================================================
// -- prototype -- << 検索用
static void OBJ_CgxChangeTrans( CATS_ACT_PTR cap, u8 * buf, u32 siz );
static void OBJ_PokeGraPallTrans( CATS_ACT_PTR p_cap, u32 arc_no, u32 pal_idx, BOOL b_LCD_main, BOOL b_gray, HEAPID heapID );
static void* OBJ_PokeIconCgxLoad( MUSEUM_OBJ_WORK* wk, u32 arc_idx, NNSG2dCharacterData** pp_chr );

//=============================================================================
/**
 *								外部公開関数
 */
//=============================================================================

CATS_SYS_PTR MUSEUM_OBJ_GetCsp( MUSEUM_OBJ_WORK* wk )
{
	GF_ASSERT(wk);
	return wk->csp;
}

CATS_RES_PTR MUSEUM_OBJ_GetCrp( MUSEUM_OBJ_WORK* wk )
{
	GF_ASSERT(wk);
	return wk->crp;
}


//-----------------------------------------------------------------------------
/**
 *	@brief	OBJシステム生成
 *
 *	@param
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
MUSEUM_OBJ_WORK* MUSEUM_OBJ_Create( HEAPID heapID, TCATS_RESOURCE_NUM_LIST* p_crnl, u32 obj_id_max )
{
	MUSEUM_OBJ_WORK* wk;

	HOSAKA_PRINT("call MUSEUM_OBJ_Create \n");

	wk = sys_AllocMemory( heapID, sizeof(MUSEUM_OBJ_WORK) );

	wk->heapID = heapID;
	wk->csp = CATS_AllocMemory( heapID );
	wk->crp = CATS_ResourceCreate( wk->csp );

	wk->p_arc_pokeicon = ArchiveDataHandleOpen( ARC_POKEICON, wk->heapID );

	wk->paloff_pokemonicon = -1;

	{
		TCATS_OAM_INIT	coi = {
			0, 128,
			0, 32,
			0, 128,
			0, 32,
		};

		TCATS_CHAR_MANAGER_MAKE ccmm = {
			0,	// dummy
			1024*128,
			1024*16,
			GX_OBJVRAMMODE_CHAR_1D_64K,
			GX_OBJVRAMMODE_CHAR_1D_64K,
		};

		ccmm.num = obj_id_max;

		CATS_SystemInit( wk->csp, &coi, &ccmm, 32 );
	}

	CATS_ClactSetInit( wk->csp, wk->crp, obj_id_max );
	CATS_ResourceManagerInit( wk->csp, wk->crp, p_crnl );

	wk->pfd = PaletteFadeInit( wk->heapID );

	GF_Disp_GX_VisibleControl(  GX_PLANEMASK_OBJ, VISIBLE_ON );		// MAIN DISP OBJ ON
	GF_Disp_GXS_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_ON );		// SUB DISP OBJ ON

	return wk;
}

//-----------------------------------------------------------------------------
/**
 *	@brief	OBJシステム削除
 *
 *	@param	MUSEUM_OBJ_WORK* wk
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MUSEUM_OBJ_Delete( MUSEUM_OBJ_WORK * wk, CATS_ACT_PTR* p_cap , u32 obj_id_max )
{
	u32 i;

	ArchiveDataHandleClose( wk->p_arc_pokeicon );
	PaletteFadeFree( wk->pfd );

	// -- ACTOR削除
	for( i=0; i<obj_id_max; i++)
	{
		if( p_cap[ i ] != NULL ){
			CATS_ActorPointerDelete_S( p_cap[ i ] );
			p_cap[ i ] = NULL;
		}
	}

	CATS_ResourceDestructor_S( wk->csp, wk->crp );
	CATS_FreeMemory( wk->csp );

	sys_FreeMemoryEz( wk );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	OBJ描画
 *
 *	@param	MUSEUM_OBJ_WORK* wk
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MUSEUM_OBJ_Draw( MUSEUM_OBJ_WORK* wk )
{
	GF_ASSERT( wk );
	CATS_Draw( wk->crp );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	OBJ追加処理
 *
 *	@param	MUSEUM_OBJ_WORK* wk
 *	@param	TCATS_OBJECT_ADD_PARAM_S* coap_s
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
CATS_ACT_PTR MUSEUM_OBJ_Add( MUSEUM_OBJ_WORK* wk, const TCATS_OBJECT_ADD_PARAM_S* coap_s )
{
	return CATS_ObjectAdd_S( wk->csp, wk->crp, coap_s );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	メーターを追加
 *
 *	@param	MUSEUM_OBJ_WORK* wk
 *	@param	MUSEUM_OBJ_ID* p_obj_id
 *	@param	num
 *	@param	head_idx
 *	@param	def_x
 *	@param	def_y
 *	@param	b_mainLCD
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MUSEUM_OBJ_AddMater( MUSEUM_OBJ_WORK* wk, CATS_ACT_PTR* p_cap, const MUSEUM_OBJ_ID* p_obj_id, u32 num, u32 head_idx, s16 def_x, s16 def_y, BOOL b_mainLCD )
{
	enum {
		OBJ_MATER_NUM = 10,	///< トロフィーメーターのメモリ数 //@@@ここで固定にするのは如何なものか
	};

	u32 i;
	TCATS_OBJECT_ADD_PARAM_S prm = {0};

	GF_ASSERT( num <= OBJ_MATER_NUM );

	for(i=0; i<OBJ_MATER_NUM; i++ )
	{
		prm.anm	= ( i < num ) ? NANR_obj_trophy_trp_single : NANR_obj_trophy_trp_none;
		prm.id[0] = p_obj_id->chr;
		prm.id[1] = p_obj_id->pal;
		prm.id[2] = p_obj_id->cel;
		prm.id[3] = p_obj_id->anm;
		prm.d_area = ( b_mainLCD ? NNS_G2D_VRAM_TYPE_2DMAIN : NNS_G2D_VRAM_TYPE_2DSUB );
		prm.x = def_x + i * 16;
		prm.y = def_y;

		p_cap[ head_idx + i ] = MUSEUM_OBJ_Add( wk, &prm );
		CATS_ObjectAutoAnimeSetCap( p_cap[ head_idx + i ], TRUE );
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	CATS_SYS_PTR csp
 *	@param	crp
 *	@param	MUSEUM_OBJ_ID* p_obj_id
 *	@param	vram_type
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MUSEUM_OBJ_POKEGRA_LoadResDummy( CATS_SYS_PTR csp, CATS_RES_PTR crp, const MUSEUM_OBJ_ID* p_obj_id, NNS_G2D_VRAM_TYPE vram_type )
{
	CATS_LoadResourceCharArc(
		csp, crp,
		ARC_BATT_OBJ, POKE_OAM_NCGR, 0, vram_type, p_obj_id->chr );

	CATS_LoadResourcePlttArc(
		csp, crp,
		ARC_BATT_OBJ, POKE_OAM_NCLR, 0, 1, vram_type, p_obj_id->pal );

	CATS_LoadResourceCellArc(
		csp, crp, ARC_BATT_OBJ, POKE_OAM_NCER, FALSE, p_obj_id->cel );

	CATS_LoadResourceCellAnmArc(
		csp, crp, ARC_BATT_OBJ, POKE_OAM_NANR, FALSE, p_obj_id->anm );
}

//-----------------------------------------------------------------------------
/**
 *	@brief	LCD_MAIN にポケグラを展開
 *
 *	@param	p_cap
 *	@param	pp
 *	@param	b_LCD_main
 *	@param	b_gray
 *	@param	HEAPID heapID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MUSEUM_OBJ_POKEGRA_Trans( CATS_ACT_PTR p_cap, const MONS_DATA* p_mons, BOOL b_LCD_main, BOOL b_gray, HEAPID heapID )
{
	enum { POKEGRA_TEX_SIZE = 0x20*100, };

	SOFT_SPRITE_ARC ssa;
	NNS_G2D_VRAM_TYPE vram_type = ( b_LCD_main ) ? NNS_G2D_VRAM_TYPE_2DMAIN : NNS_G2D_VRAM_TYPE_2DSUB;

	if( p_mons->MonsNo == 0 )
	{
		CATS_ObjectEnableCap( p_cap, CATS_ENABLE_FALSE );
		return;
	}

	// -- アーカイブデータ取得(ソフトウェアスプライト用）
	PokeGraArcDataGet( &ssa, p_mons->MonsNo, p_mons->Sex, PARA_FRONT, p_mons->Rare, p_mons->Form, p_mons->Rnd );

	// -- OAMに変換後展開
	{
		void* char_work;
		CHANGES_INTO_DATA_RECT rect = { 0, 0, 10, 10 };

		char_work = sys_AllocMemoryLo( heapID, POKEGRA_TEX_SIZE );

		HOSAKA_PRINT( "PokeGraTrans > arc_no:%d idx_chr:%d, monsNo:%d \n",ssa.arc_no, ssa.index_chr, p_mons->MonsNo );

		// TEXをOAMに変換 ※1D 64kマッピング
		Ex_ChangesInto_OAM_from_PokeTex_RC(
				ssa.arc_no, ssa.index_chr, heapID,
				&rect, char_work, p_mons->Rnd, FALSE, PARA_FRONT, p_mons->MonsNo );

		OBJ_CgxChangeTrans( p_cap , char_work, POKEGRA_TEX_SIZE );
		OBJ_PokeGraPallTrans( p_cap, ssa.arc_no, ssa.index_pal, b_LCD_main, b_gray, heapID );

		CATS_ObjectEnableCap( p_cap, CATS_ENABLE_TRUE );

		sys_FreeMemoryEz( char_work );
	}
}


//-----------------------------------------------------------------------------
/**
 *	@brief	ポケアイコン用リソースをロード
 *
 *	@param	MUSEUM_OBJ_WORK* wk			ワークポインタ
 *	@param	MUSEUM_OBJ_ID* p_obj_id		先頭リソースID
 *	@param	num
 *	@param	b_disp_m
 *	@param	b_anm
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MUSEUM_OBJ_POKEICON_LoadRes( MUSEUM_OBJ_WORK* wk, const MUSEUM_OBJ_ID* p_obj_id, int num, BOOL b_disp_m, BOOL b_anm )
{
	static const type[2] =
	{
		NNS_G2D_VRAM_TYPE_2DSUB,
		NNS_G2D_VRAM_TYPE_2DMAIN,
	};

	CATS_SYS_PTR csp;
	CATS_RES_PTR crp;
	u32 cgr_idx, cell_idx, anm_idx;
	int i;

	csp = wk->csp;
	crp = wk->crp;

	cgr_idx		= b_anm ? NARC_pkth_museum_pokeicon_dmy_lz_NCGR : NARC_pkth_museum_pokeicon_dmy_noanm_lz_NCGR;
	cell_idx	= PokeIcon64kCellArcIndexGet();
	anm_idx		= PokeIcon64kCellAnmArcIndexGet();

	for( i=0; i<num; i++ )
	{
		CATS_LoadResourceCharArc(	 csp, crp, ARC_PKTH_MUSEUM_GRA, cgr_idx, TRUE, type[ b_disp_m ], p_obj_id->chr + i );
	}

	CATS_LoadResourceCellArc(	 csp, crp, ARC_POKEICON, cell_idx,	0, p_obj_id->cel );
	CATS_LoadResourceCellAnmArc( csp, crp, ARC_POKEICON, anm_idx,	0, p_obj_id->anm );

	// -- 初回のみ読み込み
	// @@@ このままだと、2画面同時にアイコンが出せない
	if( wk->paloff_pokemonicon == -1 )
	{
		wk->paloff_pokemonicon =
			CATS_LoadResourcePlttArc( csp, crp, ARC_POKEICON, PokeIconPalArcIndexGet(), 0, POKEICON_PAL_MAX, type[ b_disp_m ], p_obj_id->pal );
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	ポケモンアイコン　描画
 *
 *	@param	MUSEUM_OBJ_WORK* wk
 *	@param	p_cap
 *	@param	pp
 *	@param	b_LCD_main
 *	@param	b_anm
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MUSEUM_OBJ_POKEICON_Draw( MUSEUM_OBJ_WORK* wk, CATS_ACT_PTR p_cap, const MONS_DATA* p_mons, BOOL b_LCD_main, BOOL b_anm )
{
	enum{
		POKEICON_CGX_SIZE = 0x20*4*4,
	};

	u32 egg;
	u32 monsno;
	u32 form;
	u32 cgx_size = POKEICON_CGX_SIZE;
	int arc;
	void* buf;
	NNSG2dCharacterData* p_chr;

	if( b_anm ){ cgx_size *= 2; }

	egg = FALSE;
	monsno = p_mons->MonsNo;
	form = p_mons->Form;

	arc = PokeIconCgxArcIndexGetByMonsNumber( monsno, egg, form );

	buf = OBJ_PokeIconCgxLoad( wk, arc, &p_chr );
	OBJ_CgxChangeTrans( p_cap, p_chr->pRawData, cgx_size );
	sys_FreeMemoryEz( buf );

	CATS_ObjectEnableCap( p_cap, FALSE );

	// 参照パレット調整
	{
		u8 pal;
		int offset = wk->paloff_pokemonicon;

		pal = PokeIconPalNumGet( monsno, form, egg );

		// @@@
		// このタイミングでポケモンアイコンを読み込んだパレットオフセットを取得できないか？
		CATS_ObjectPaletteSetCap( p_cap, pal + wk->paloff_pokemonicon );
//		HOSAKA_PRINT( "offset:%d, pal:%d \n", offset, pal);
	}

	// アニメ設定
	if( b_anm )
	{
		CATS_ObjectAnimeSeqSetCap( p_cap, POKEICON_ANM_HPMAX );
		CATS_ObjectAutoAnimeSpeedSetCap( p_cap, FX32_ONE );
		CATS_ObjectAutoAnimeSetCap( p_cap, TRUE );
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief	OBJに割り当てられているキャラデータ（CGX）を書き換える
 *
 *	@param	cap
 *	@param	buf
 *	@param	siz
 *	@param	b_LCD_main
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
void MUSEUM_OBJ_CgxChangeTrans( CATS_ACT_PTR cap, u8* buf, u32 siz )
{
	OBJ_CgxChangeTrans( cap, buf, siz );
}

//=============================================================================
/**
 *								static関数
 */
//=============================================================================

//-----------------------------------------------------------------------------
/**
 *	@brief	OBJに割り当てられているキャラデータ（CGX）を書き換える
 *
 *	@param	cap
 *	@param	* buf
 *	@param	siz
 *	@param	b_LCD_main
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void OBJ_CgxChangeTrans( CATS_ACT_PTR cap, u8 * buf, u32 siz )
{
	NNSG2dImageProxy * ipc;
	u32	cgx;
	NNS_G2D_VRAM_TYPE vram_type;

	vram_type = CLACT_VramTypeGet( cap->act );
	ipc = CLACT_ImageProxyGet( cap->act );
	cgx = NNS_G2dGetImageLocation( ipc, vram_type );

	DC_FlushRange( buf, siz );

	switch( vram_type )
	{
		case NNS_G2D_VRAM_TYPE_2DMAIN:
			GX_LoadOBJ( buf, cgx, siz );
			break;

		case NNS_G2D_VRAM_TYPE_2DSUB:
			GXS_LoadOBJ( buf, cgx, siz );
			break;

		default : GF_ASSERT(0);
	};

}


//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	p_cap
 *	@param	arc_no
 *	@param	pal_idx
 *	@param	b_LCD_main
 *	@param	b_gray
 *	@param	heapID
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void OBJ_PokeGraPallTrans( CATS_ACT_PTR p_cap, u32 arc_no, u32 pal_idx, BOOL b_LCD_main, BOOL b_gray, HEAPID heapID )
{
	enum { POKEGRA_PAL_SIZE = 0x20, };

	u32 pal;
	NNS_G2D_VRAM_TYPE vram_type;
	PALTYPE pal_type;

	if( b_LCD_main )
	{
		vram_type = NNS_G2D_VRAM_TYPE_2DMAIN;
		pal_type = PALTYPE_MAIN_OBJ;
	}
	else
	{
		vram_type = NNS_G2D_VRAM_TYPE_2DSUB;
		pal_type = PALTYPE_SUB_OBJ;
	}

	{
		NNSG2dImagePaletteProxy * ipp;
		ipp  = CLACT_PaletteProxyGet( p_cap->act );
		pal = NNS_G2dGetImagePaletteLocation( ipp, vram_type );
	}

	ArcUtil_PalSet( arc_no, pal_idx, pal_type, pal, POKEGRA_PAL_SIZE, heapID );

	// -- グレースケール化 --
	if( b_gray )
	{
		u16* p_adr;
		p_adr = b_LCD_main ? (void*)(HW_OBJ_PLTT + pal) : (void*)(HW_DB_OBJ_PLTT + pal);
		PaletteGrayScale( p_adr, POKEGRA_PAL_SIZE );
	}
}

//-----------------------------------------------------------------------------
/**
 *	@brief
 *
 *	@param	MUSEUM_OBJ_WORK* wk
 *	@param	arc_idx
 *	@param	pp_chr
 *
 *	@retval
 */
//-----------------------------------------------------------------------------
static void* OBJ_PokeIconCgxLoad( MUSEUM_OBJ_WORK* wk, u32 arc_idx, NNSG2dCharacterData** pp_chr )
{
	void * buf;
	buf = ArcUtil_HDL_CharDataGet( wk->p_arc_pokeicon, arc_idx, FALSE, pp_chr, wk->heapID );
	return buf;
}